/*
 * @Author: zxc
 * @Date: 2020-08-03 09:56:08
 * @LastEditTime: 2020-08-03 11:15:00
 * @LastEditors: zxc
 * @Description: ts中的类的使用
 */
class Point {
  public x: number;
  public y: number;
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
  public getPosition() {
    return `(${this.x},${this.y})`;
  }
}
let apoint = new Point(2, 3);
// console.log(apoint)ƒ

class Parent {
  public name: string;
  constructor(name: string) {
    this.name = name;
  }
}

class Child extends Parent {
  constructor(name: string) {
    super(name);
  }
}

// public 修饰符 表示公共
class PublicClassTest {}

// private 表示私有（天王老子来了也只有自己可以访问 ）
class PrivateClassTest {
  private age: number;
  constructor(age: number) {
    this.age = age;
  }
}
class PrivateClassTestChild extends PrivateClassTest {
  constructor(age: number) {
    super(age);
    // console.log(super.age)
  }
}
// let p = new PrivateClassTest(24)
// console.log(p);

// protected 受保护（子类可访问受保护的方法） 在consturctor 使用protected的话，那么这个类就只能被继承，而不能被创建实例
class ProtectedClassTest {
  protected age: number;
  constructor(age: number) {
    this.age = age;
  }
  protected getAge(){
    return this.age
  }
}
class ProtectedClassTestChild extends ProtectedClassTest {
  constructor(age: number) {
    super(age);
    // console.log(super.getAge())
    // console.log(super.age)
  }
}
let pro = new ProtectedClassTestChild(18)

// readonly 属性为只读
class UserInfo{
  public readonly name:string
  constructor(name:string){
    this.name = name
  }
}

let us = new UserInfo('zc')
// us.name = 234
// console.log(us)


// 参数属性 
class A{
  constructor(public name:string){
    this.name = name
  }
}

const a = new A('zxc')

// 静态属性
class S{
  private static age:number = 18
  // tslint:disable-next-line:no-empty
  constructor(){
    
  }
  public static getApage(){
    return S.age
  }
}
let s = new S()
// console.log(s.age)
// console.log(S.age)
// console.log(S.getApage())

// 可选类属性
class Info{
  public name: string;
  public age?: number;
  private _infoStr!: string;
  constructor(name: string, age?: number,public sex?:string){
    this.name = name
    this.age = age
  } 
  get infoStr(){
    return this._infoStr
  }
  set infoStr(val){
    // console.log(val)
    this._infoStr = val;
  }
}
// let info1 = new Info('zs')
// let info2 = new Info('zs',18)
// let info3 = new Info('zs',18,'nan')
// console.log(info1)
// console.log(info2)
// console.log(info3)
let info4 = new Info('zs',18,'nan')
info4.infoStr = "zdf:9"
// console.log(info4.infoStr)


// 抽象类
abstract class People{
  constructor(public name:string){}
  public abstract printName():void
}
// let p1 = new People()

class Man extends People{
  constructor(name:string){
    super(name)
    this.name = name
  }
  public printName(){
    console.log(this.name)
  }
}
let p1 = new Man('a')
// p1.printName()

abstract class Peo{
  abstract _name:string
  abstract get insideName():string
  abstract set insideName(value:string)
}
class Ma extends Peo{
  public _name!: string;
  public insideName!: string;
}

// 实例属性
//  阿巴阿巴阿巴
class P{
  constructor(public name:string){}
}
class An{
  constructor(public name:string){}
}
let newp:P = new P('ha')
newp=new An('aba')


// 类类型接口
interface FoodInterface{
  type:string
  name:string
}
class FoodClass implements FoodInterface{
  public type!: string;
  public name!: string;
} 

// 接口继承类
class AA{
  protected name!: string;
}
interface I extends AA{}
class B extends AA implements I{
  public name!: string;
}

// 泛型中使用类类型
// 传入了一介类，返回的是一个类创建的实例
const create = <T>(c:new() => T):T=> {
  return new c()
}
class Infos{
  public age!:number
}
create<Infos>(Infos)